home *** CD-ROM | disk | FTP | other *** search
-
-
- /*
- * RANDIO.C by Ed Mulroy
- *
- * Simple demo of random access in files
- *
- * A file with 10 records is created
- *
- * Each record consists of the number of the record repeated 13 times
- * followed by a <cr><lf> so that it could be viewed with a text editor
- *
- * The user can select record number to display, or can ask to see them all
- *
- * Illustrations of how to do certain things:
- *
- * Random access by record number -
- * read_record()
- * display_all_records()
- *
- * Getting the file size and number of records in a FILE * type file:
- * num_records_in_file()
- *
- * Getting a key from the keyboard, including function key values
- * get_key()
- * #define macro F()
- *
- * While written as C code, this should work as C or C++ in any memory model
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h> /* for prototype of memset() */
- #include <conio.h> /* for prototype of getch() */
-
-
- #define RECORD_SIZE 15 /* number of bytes in one record */
- #define ESCAPE '\x1B' /* escape key value */
-
- #define F(N) ((0x3A + N) << 8)
-
-
- unsigned num_records;
- FILE *fptr;
-
- char *filename = "DEMO.DAT";
- char *prompt =
- "\nEnter record number [0-9] 'A' for all or press <Esc> to end ";
-
- char *helpstring =
- "\n"
- "\n"
- "\tRANDIO.C by Ed Mulroy\n"
- "\n"
- "\tSimple demo of random access in files\n"
- "\n"
- "\tA file with 10 records is created. Each record consists of\n"
- "\tthe number of the record repeated 13 times followed by a\n"
- "\t<cr><lf> so that it can be viewed with a text editor. The\n"
- "\tuser can select record number to display, or can ask to see\n"
- "\tthem all\n";
-
-
-
- /* display system error message and quit with an error exit code */
- void fatal(void)
- {
- perror("");
- exit(EXIT_FAILURE);
- }
-
-
-
-
- /*
- * Read normal keys as you would expect and special keys as a
- * value with 0 as the low byte and a number in the high byte
- *
- * The special key values are the same as would be returned if
- * the BIOS were called.
- *
- * Does not detect an enhanced keyboard nor respond to its extra
- * special keys such as F11 and F12
- */
- int get_key(void)
- {
- int i;
-
- i = getch(); /* get normal keys as the expected value */
-
- if (!i) /* if function or special key, get it also */
- i = getch() << 8;
-
- return i;
- }
-
-
-
-
- int create_file(void)
- {
- char buffer[RECORD_SIZE]; /* array of char's, not a string */
- char c;
-
- fptr = fopen(filename, "w+b"); /* note the binary mode open */
-
- if (fptr == NULL)
- return 0;
-
- buffer[RECORD_SIZE - 2] = '\r'; /* make record buffer end in a newline */
- buffer[RECORD_SIZE - 1] = '\n'; /* so a text editor can look at it */
-
- for (c = '0'; c <= '9'; c++)
- {
- memset(buffer, c, RECORD_SIZE - 2);
- fwrite(buffer, sizeof(buffer), 1, fptr);
-
- if (ferror(fptr))
- return 0;
- }
-
- return 1;
- }
-
-
-
-
- int read_record(FILE *f, void *buffer, unsigned rec_num, unsigned rec_size)
- {
- /* position in file, fseek() returns 0 on success */
- if (fseek(f, rec_num * (long) rec_size, SEEK_SET) == 0)
- {
- if (fread(buffer, rec_size, 1, f) == 1) /* read the record */
- return 1;
- }
-
- return 0;
- }
-
-
-
-
- void display_all_records(void)
- {
- unsigned rec_num;
- char buffer[RECORD_SIZE];
-
- printf("\nFile has %d records\n"
- "Displaying them in reverse order\n", num_records);
-
- if (num_records < 1)
- return;
-
- /* illustrate seeking in the file by reading and showing */
- /* odd records and then even ones in descending order */
- for (rec_num = (num_records - 1) | 1; rec_num != 0xFFFEU; rec_num -= 2)
- {
- if (rec_num == 0xFFFFU) /* if done with odd records */
- rec_num = (num_records - 1) & ~1; /* start with highest even one */
-
- fseek(fptr, rec_num * RECORD_SIZE, SEEK_SET);
- fread(buffer, RECORD_SIZE, 1, fptr);
- printf("%3u: ", rec_num);
- fwrite(buffer, RECORD_SIZE, 1, stdout);
- }
-
- putchar('\n');
- }
-
-
-
-
- int num_records_in_file(FILE *fileptr, unsigned record_size)
- {
- long pos_b4;
- long file_size;
-
- if (record_size == 0) /* trap possible divide by 0 error */
- return 0;
-
- pos_b4 = ftell(fileptr); /* save current position */
- fseek(fileptr, 0, SEEK_END); /* go to end of file */
- file_size = ftell(fileptr); /* get position as the file size */
- fseek(fileptr, pos_b4, SEEK_SET); /* restore old position */
- return (unsigned) (file_size / record_size);
- }
-
-
-
-
- int main()
- {
- int keyin;
- unsigned record_num;
- char buffer[RECORD_SIZE];
-
- puts("RANDIO random file I/O demo - press F1 at any time for help\n");
-
- if (!create_file())
- fatal();
-
- num_records = num_records_in_file(fptr, RECORD_SIZE);
-
- do
- {
- fputs(prompt, stdout);
-
- do /* loop until valid input received */
- {
- putchar('\b'); /* back up to position where key will be shown */
- keyin = get_key();
-
- if (keyin == F(1))
- {
- puts(helpstring);
- fputs(prompt, stdout); /* fputs() doesn't add a newline at end */
- }
- else if (keyin == 'a')
- keyin = 'A';
-
- if ((keyin >= ' ') && (keyin <= '~'))
- putchar(keyin); /* if a printable key show it */
- else
- putchar('?'); /* show '?' for non-printable key */
-
- } while ((keyin != ESCAPE) && (keyin != 'A') &&
- !((keyin >= '0') && (keyin <= '9')));
-
- if ((keyin >= '0') && (keyin <= '9'))
- {
- record_num = keyin - '0';
- putchar('\n');
-
- if (!read_record(fptr, buffer, record_num, RECORD_SIZE))
- fatal();
-
- printf("\nRecord #%3u: ", record_num);
- fwrite(buffer, RECORD_SIZE, 1, stdout);
- putchar('\n');
- }
- else if (keyin == 'A')
- display_all_records();
-
- } while (keyin != ESCAPE);
-
- fclose(fptr);
- putchar('\n');
- return EXIT_SUCCESS;
- }
-
-
-